<?php
/*
	Copyright 2006, 2007, 2008, 2009, 2010 Bastiaan Grutters
    
    This file is part of Ages of Strife website.

    Ages of Strife website is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Ages of Strife website is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Ages of Strife website.  If not, see <http://www.gnu.org/licenses/>.
 */
class DatabaseAbstractionLayer {
	private $connection = null;
	private $is_active = false;
	private $debug = false;
	private $mail_address = '';
	private $lastQuery = '';
	
	/*
	 * We need to create a database object to be able to use the database
	 * 
	 * If initialization fails we won't provide any information except that it failed
	 * no need to allow too much information to show up here
	 */
	public function __construct( $databaseHost = null, $databaseUser = null, $databasePassword = null, $databaseName = null ) {
		try {
			$this->connection = new PDO( 'mysql:host=' . ( isset( $databaseHost ) ? $databaseHost : DATABASE_HOST ) . ';dbname=' . ( isset( $databaseName ) ? $databaseName : DATABASE_NAME ), ( isset( $databaseUser ) ? $databaseUser : DATABASE_USER ), ( isset( $databasePassword ) ? $databasePassword : DATABASE_PASSWORD ) );
    		$this->connection->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
    		$is_active = true;
    		if( DEBUG ) {
    			$this->setDebug( true );
    		} 
		}
		catch( PDOException $e ) {
    		$is_active = false;
?>
				There was a problem setting up the database connection.<br />
				<br />
				Make sure you have set up the configuration properly.<br />
				<br />
				Error message: <?php print( $e->getMessage() ); ?><br />
<?php
		}
	}

	public function getValue( $statement ) {
		$value = null;
		try {
			$statement->execute();
			$row = $statement->fetch( PDO::FETCH_NUM );
			if( $row && is_array( $row ) && isset( $row[0] ) ) {
				$value = $row[0];
				if( $value === FALSE ) {
					$value = null;
				}
			}
		}
		catch( PDOException $e ) {
			$this->printMysqlErrorMessage( $e );
		}
		return $value;
	}
	
	public function getObject( $statement ) {
		$value = null;
		try {
			$statement->execute();
			if( ( $value = $statement->fetchObject() ) === FALSE ) {
				$value = null;
			}
		}
		catch( PDOException $e ) {
			$this->printMysqlErrorMessage( $e );
		}
		return $value;
	}
	
	public function getArray( $statement ) {
		$value = null;
		try {
			$statement->execute();
			if( ( $value = $statement->fetch( PDO::FETCH_ASSOC ) ) === FALSE ) {
				$value = null;
			}
		}
		catch( PDOException $e ) {
			$this->printMysqlErrorMessage( $e );
		}
		return $value;
	}
	
	public function getArrayOfObjects( $statement ) {
		$values = Array();
		try {
			$statement->execute();
			while( $value = $statement->fetchObject() ) {
				$values[] = $value;
			}
		}
		catch( PDOException $e ) {
			$this->printMysqlErrorMessage( $e );
		}
		return $values;
	}
	
	public function getArrayOfArrays( $statement ) {
		$values = Array();
		try {
			$statement->execute();
			while( $value = $statement->fetch( PDO::FETCH_ASSOC ) ) {
				$values[] = $value;
			}
		}
		catch( PDOException $e ) {
			$this->printMysqlErrorMessage( $e );
		}
		return $values;
	}
	
	public function getArrayOfValues( $statement ) {
		$values = Array();
		try {
			$statement->execute();
			while( $value = $statement->fetch( PDO::FETCH_ASSOC ) ) {
				$values[] = array_shift( $value );
			}
		}
		catch( PDOException $e ) {
			$this->printMysqlErrorMessage( $e );
		}
		return $values;
	}
	
	public function execute( $statement ) {
		$check = false;
		try {
			$check = $statement->execute();
		}
		catch( PDOException $e ) {
			$this->printMysqlErrorMessage( $e );
		}
		return $check;
	}
	
	public function prepare( $query ) {
		$statement = null;
		$this->lastQuery = $query;
		try {
			$statement = $this->connection->prepare( $query );
		}
		catch( PDOException $e ) {
			$this->printMysqlErrorMessage( $e );
		}
		return $statement;
	}
	
	public function isActive() {
		return $this->is_active;
	}

	public function getDebug() {
		return $this->debug;
	}

	public function setDebug( $debug ) {
		$this->debug = $debug;
	}

	public function getMailAddress() {
		return $this->mail_address;
	}

	public function setMailAddress( $mail_address ) {
		$this->mail_address = $mail_address;
	}

	/*
	 * This function formats and prints the query and the error the query triggered
	 */
	private function printMysqlErrorMessage( $error ) {
		if( $this->debug ) {
?>
				<div class="mysql-error-message">
					<strong>A database error occurred</strong><br />
					Last query: <?php print( $this->lastQuery ); ?><br />
					Error message: <?php print( $error->getMessage() ); ?><br />
				</div>
<?php
		}
		else {
			$title = 'An error occured at ' . SITE_URL;
			$mail = "The URL: " . $_SERVER[ 'request_uri' ] . "\n" .
					"File: '{$error->getFile()}'\n" .
					"Line: '{$error->getLine()}'\n" .
					"Error message: '{$error->getMessage()}'";
			$header = 	'From: error@' . SITE_URL . "\r\n" .
						'Reply-To: error@' . SITE_URL . "\r\n" .
						'X-Mailer: PHP/' . phpversion();
			mail( $this->mail_address, $title, $mail, $header );
?>
				<div class="mysql-error-message">
					<strong>A database error occurred</strong><br />
					An administrator has been notified of the problem and will try to resolve it as soon as possible.
				</div> 
<?php
		}
		exit();
	}
	
	private function getLastQuery() {
		return $this->lastQuery;
	}
	
	public function getLastInsertedId() {
		return $this->connection->lastInsertID();		
	}
}
?>